#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>

gpointer ws_ob2_parent_class = NULL;


#define WS_TYPE_OB1 ws_ob1_get_type()

typedef struct _WsOb1{
    GObject parent;
    
}WsOb1;

typedef struct _WsOb1Class{
    GObjectClass parent_class;
}WsOb1Class;

GType ws_ob1_get_type();
void ws_ob1_init(WsOb1 * obj)
{
    g_print("ob1_init\n");
}

void ws_ob1_class_finalize(WsOb1Class * klass)
{
    g_print("ob1_class_finalized\n");
}
void ws_ob1_base_init(WsOb1Class * klass)
{
    g_print("ob1_base_init\n");
}
void ws_ob1_base_finalize(WsOb1Class * klass)
{
    
    g_print("ob1_base_finalized\n");
}

void ws_ob1_dispose(WsOb1 * obj)
{
    g_print("ws_ob1_dispose\n");
}

void ws_ob1_finalize(WsOb1 * obj)
{
    g_print("ws_ob1_finalize\n");
}

void ws_ob1_class_init(WsOb1Class * klass)
{ 
    g_print("ob1_class_init\n");
    G_OBJECT_CLASS(klass)->dispose = ws_ob1_dispose;
    G_OBJECT_CLASS(klass)->finalize = ws_ob1_finalize;
 
    g_signal_new("signalob1",
                    WS_TYPE_OB1,
                    G_SIGNAL_RUN_LAST,
                    0,
                    NULL,
                    NULL,
                    //g_cclosure_marshal_VOID__POINTER,
                    NULL,
                    G_TYPE_NONE,
                    1,
                    G_TYPE_POINTER);

}


GType ws_ob1_get_type()
{
    static GType mtype = 0;
    if (!mtype) {
        const GTypeInfo type_info = {
            sizeof(WsOb1Class),
            (GBaseInitFunc)ws_ob1_base_init,
            (GBaseFinalizeFunc)ws_ob1_base_finalize,
            (GClassInitFunc)ws_ob1_class_init,
            //(GClassFinalizeFunc)ws_ob1_class_finalize,
            (GClassFinalizeFunc) NULL,
            NULL,
            sizeof(WsOb1),
            0,
            (GInstanceInitFunc)ws_ob1_init,
            NULL
        };
        
        mtype = g_type_register_static(G_TYPE_OBJECT, "WsOb1", &type_info, 0);

    }
    return mtype;
}


#define WS_TYPE_OB2 ws_ob2_get_type()

typedef struct _WsOb2{
    WsOb1 parent;
    char * data;
    
}WsOb2;

typedef struct _WsOb2Class{
    WsOb1Class parent_class;
}WsOb2Class;


void ws_ob2_callback(WsOb2 * obj, gpointer * para, gpointer * user_data)
{
    g_print("obj_data:%s\npara:%s\nuser_data:%s\n", obj->data, (char *)para, (char *)user_data);
    
}


GType ws_ob2_get_type();
void ws_ob2_init(WsOb2 * obj)
{
    g_print("ob2_init\n");
    obj->data = "ob_data";
}

void ws_ob2_class_finalize(WsOb2Class * klass)
{
    g_print("ob2_class_finalized\n");
}
void ws_ob2_base_init(WsOb2Class * klass)
{
    g_print("ob2_base_init\n");
}
void ws_ob2_base_finalize(WsOb2Class * klass)
{
    
    g_print("ob2_base_finalized\n");
}

void ws_ob2_dispose(WsOb2 * obj)
{
    g_print("ws_ob2_dispose\n");

    ((GObjectClass *)ws_ob2_parent_class)->dispose((WsOb1 *)obj);
}

void ws_ob2_finalize(WsOb2 * obj)
{
    g_print("ws_ob2_finalize\n");
    ((GObjectClass *)ws_ob2_parent_class)->finalize((WsOb1 *)obj);
}

void ws_ob2_class_init(WsOb2Class * klass)
{ 
    ws_ob2_parent_class = g_type_class_peek_parent(klass);
    g_print("ob2_class_init\n");
    G_OBJECT_CLASS(klass)->dispose = ws_ob2_dispose;
    G_OBJECT_CLASS(klass)->finalize = ws_ob2_finalize;
    
    g_signal_new("signal",
                    WS_TYPE_OB2,
                    G_SIGNAL_RUN_LAST,
                    0,
                    NULL,
                    NULL,
                    //g_cclosure_marshal_VOID__POINTER,
                    NULL,
                    G_TYPE_NONE,
                    1,
                    G_TYPE_POINTER);

}


GType ws_ob2_get_type()
{
    static GType mtype = 0;
    if (!mtype) {
        const GTypeInfo type_info = {
            sizeof(WsOb1Class),
            (GBaseInitFunc)ws_ob2_base_init,
            //(GBaseFinalizeFunc)ws_ob2_base_finalize,
            (GBaseFinalizeFunc) NULL,
            (GClassInitFunc)ws_ob2_class_init,
            //(GClassFinalizeFunc)ws_ob1_class_finalize,
            (GClassFinalizeFunc) NULL,
            NULL,
            sizeof(WsOb2),
            0,
            (GInstanceInitFunc)ws_ob2_init,
            NULL
        };
        
        mtype = g_type_register_static(WS_TYPE_OB1, "WsOb2", &type_info, 0);

    }
    return mtype;
}




int main(int argc, char ** argv)
{
    g_print("hello\n");
    
    WsOb2 * ob1  = g_object_new(WS_TYPE_OB2, NULL);
    //WsOb2 * ob2  = g_object_new(WS_TYPE_OB2, NULL);
    g_signal_connect(ob1, "signal", (GCallback)ws_ob2_callback, "connect_user_data");
    g_signal_emit_by_name(ob1, "signal", "emit_data");

    g_object_unref(ob1);
    //g_object_unref(ob2);
    //g_object_unref(ob1);

    return 0;
}
